package com.hmall.order.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmall.common.pojo.Address;
import com.hmall.common.pojo.Item;
import com.hmall.order.dto.OrderDTO;
import com.hmall.common.feign.ItemClient;
import com.hmall.common.feign.UserClient;
import com.hmall.order.mapper.OrderDetailMapper;
import com.hmall.order.mapper.OrderLogisticsMapper;
import com.hmall.order.mapper.OrderMapper;
import com.hmall.order.pojo.*;
import com.hmall.order.service.IOrderService;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.UUID;

@Service
public class OrderService extends ServiceImpl<OrderMapper, Order> implements IOrderService {
    @Autowired
    private ItemClient itemClient;
    @Autowired
    private UserClient userClient;

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private OrderLogisticsMapper orderLogisticsMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 创建订单 扣减库存
     * @param orderDTO
     * @return
     */
    @GlobalTransactional
    @Override
    public Order createOrder(OrderDTO orderDTO) {
        //购买的商品id
        Long itemId = orderDTO.getItemId();
        //购买商品的数量num
        Integer num = orderDTO.getNum();
        //1.调用商品微服务  获取商品 item
        Item item = itemClient.listById(itemId);
        //获取商品的价格 price
        Long price = item.getPrice();
        //2.构造订单没有数据的字段
        Order order = new Order();
        //2.1 计算商品总价 totalFee
        order.setTotalFee(price * num);
        order.setStatus(1);//设置订单状态
        order.setCreateTime(new Date());//订单创建时间
        order.setPaymentType(orderDTO.getPaymentType());//支付方式
        //获取用户id
        Address address = userClient.findAddressById(orderDTO.getAddressId());
        Long userId = address.getUserId();
        order.setUserId(userId);
        //插入订单数据
        orderMapper.insert(order);
        //构建OrderDetail对象
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(order.getId());
        orderDetail.setItemId(itemId);
        orderDetail.setNum(num);
        orderDetail.setName(item.getName());
        orderDetail.setSpec(item.getSpec());
        orderDetail.setPrice(order.getTotalFee());
        orderDetail.setImage(item.getImage());
        orderDetail.setCreateTime(order.getCreateTime());
        //orderDetail表里插入数据
        orderDetailMapper.insert(orderDetail);
        //构建orderLogistics对象
        OrderLogistics orderLogistics = new OrderLogistics();
        BeanUtils.copyProperties(address, orderLogistics);
        orderLogistics.setOrderId(order.getId());
        orderLogistics.setLogisticsCompany("豪俊绅峰明可物流");
        orderLogistics.setLogisticsNumber(UUID.randomUUID().toString());//可用UUID
        orderLogistics.setCreateTime(new Date());
        //orderLogistics表里插入数据
        orderLogisticsMapper.insert(orderLogistics);
        //发送延迟消息
        // 创建消息
        Message message = MessageBuilder
                .withBody(order.getId().toString().getBytes(StandardCharsets.UTF_8))
                .setHeader("x-delay",1800000) //延迟30分钟
                .build();    // 消息ID，需要封装到CorrelationData中
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        // 发送消息
        rabbitTemplate.convertAndSend("delay.direct", "delay", message, correlationData);
        log.debug("延迟消息发送成功了");

        //下单成功减去库存  调用item-service提供的减库存接口
        Integer stock = item.getStock();
        item.setStock(stock-num);
        //更新库存
        itemClient.updateById(item);
        return order;
    }
}
